import { toSuccess, useEntityManager, useRedis } from "@sker/core"
import { AutoUser, KsDevice, KsLiveRoomDayLog, KsLiveRoomLog } from "@sker/entities"
import { useData } from "@sker/runtime"
import dayjs from "dayjs"
import { z } from "zod"
import { Core, CoreDevice } from "./core/core"

export default async () => {
    const input = z.object({
        id: z.number(),
        count: z.optional(z.number().default(0)),
        uuid: z.string(),
        pkg: z.optional(z.string()),
        online: z.optional(z.number()),
        total: z.optional(z.number())
    })
    const body = input.parse(useData())
    body.count = body.count || 0;
    let result: boolean = true;
    await useEntityManager(async m => {
        const device = await m.findOne(KsDevice, { where: { uuid: body.uuid } })
        const log = await m.findOne(KsLiveRoomLog, { where: { id: body.id } })
        await m.update(KsLiveRoomLog, body.id, {
            count: body.count,
            status: body.count > 0 ? '1' : '2',
        });
        await useRedis(8, async r => {
            const key = `red.${body.uuid}`
            const value = await r.get(key)
            if (value) {
                const json = JSON.parse(value)
                let { link, ksSuccess, ksFail, jsSuccess, jsFail, ksMoney, jsMoney, success, fail, money, ksLianXuFail, jsLianXuFail, ksLianXuSuccess, jsLianXuSuccess } = json;
                success = parseInt(success)
                fail = parseInt(fail)
                if (body.count > 0) {
                    success += 1;
                    await useRedis(7, async r => {
                        const core = new Core(r)
                        const coreDevice = new CoreDevice()
                        coreDevice.owner = device.owner;
                        coreDevice.uuid = device.uuid;
                        coreDevice.score = Math.floor(100 * success / link) / 100;
                        await core.updateDeviceScore(coreDevice)
                    });
                    money += body.count;
                } else {
                    fail += 1;
                    await useRedis(7, async r => {
                        const core = new Core(r)
                        const coreDevice = new CoreDevice()
                        coreDevice.owner = device.owner;
                        coreDevice.uuid = device.uuid;
                        coreDevice.score = Math.floor(100 * success / link) / 100;
                        await core.updateDeviceScore(coreDevice)
                    });
                }
                if (body.pkg === `com.smile.gifmaker`) {
                    if (body.count > 0) {
                        ksSuccess += 1;
                        ksLianXuSuccess += 1;
                        ksMoney += body.count;
                        ksLianXuFail = 0;
                    } else {
                        ksFail += 1;
                        ksLianXuFail += 1;
                        ksLianXuSuccess = 0;
                    }
                } else {
                    if (body.count > 0) {
                        jsSuccess += 1;
                        jsMoney += body.count;
                        jsLianXuSuccess += 1;
                        jsLianXuFail = 0;
                    } else {
                        jsFail += 1;
                        jsLianXuFail += 1;
                        jsLianXuSuccess = 0;
                    }
                }
                const setting = device.setting;

                let totalFailCount = setting.totalFailCount || 0;
                setting.totalSleepCount = setting.totalSleepCount || 0;
                setting.log = setting.log || {}
                const hourKey = `${dayjs().format('YYYYMMDDHH')}`
                let log = setting.log[hourKey] || {
                    count: 0,
                    time: dayjs().toDate().getTime()
                };
                if (typeof log === 'number') {
                    log = {
                        count: 0,
                        time: dayjs().toDate().getTime()
                    }
                }
                log.count = log.count + 1;
                setting.log[hourKey] = log;
                if (body.total && body.online) {
                    if (body.count > 0) {
                        setting.totalFailCount = 0;
                    } else {
                        setting.totalFailCount = totalFailCount + 1;
                        const max: number = setting.failCount || 6;
                        if (totalFailCount >= max) {
                            setting.totalFailCount = 0;
                            setting.stopTime = dayjs().add(setting.needSleepTime || 60, 'minute').format('YYYY-MM-DD HH:mm:ss')
                            if (device.owner === '18639118753') {
                                const user = await m.findOne(AutoUser, { where: { mobile: device.owner } })
                                if (user) {
                                    const setting = user.setting || {};
                                    const nextHour = dayjs().add(1, 'hour').get('hour')
                                    const currentHour = dayjs().get('hour')
                                    const hours = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
                                    setting.hours = hours.filter(it => ![nextHour, currentHour].includes(it))
                                }
                            }
                        }
                    }
                    await m.update(KsDevice, device.id, { setting: setting })
                }
                await r.set(key, JSON.stringify({
                    ...json,
                    ksSuccess,
                    ksFail,
                    jsSuccess,
                    jsFail,
                    ksMoney,
                    jsMoney,
                    success,
                    fail,
                    money,
                    ksLianXuFail,
                    jsLianXuFail,
                    ksLianXuSuccess,
                    jsLianXuSuccess,
                    owner: device.owner,
                    device_id: device.id,
                    uuid: device.uuid
                }))
                const endDate = dayjs().endOf('day').toDate().getTime()
                const expirationTime = Math.floor((endDate - new Date().getTime()) / 1000)
                await r.expire(key, expirationTime);
            } else {
                await r.set(key, JSON.stringify({
                    ksSuccess: 0,
                    ksFail: 0,
                    jsSuccess: 0,
                    jsFail: 0,
                    ksMoney: 0,
                    jsMoney: 0,
                    success: '',
                    totalFailCount: 0,
                    fail: 0,
                    money: 0,
                    ksLianXuFail: 0,
                    jsLianXuFail: 0,
                    ksLianXuSuccess: 0,
                    jsLianXuSuccess: 0,
                    join: 0,
                    link: 0,
                    ksJoin: 0,
                    jsJoin: 0,
                    owner: device.owner,
                    device_id: device.id,
                    uuid: device.uuid
                }));
                const endDate = dayjs().endOf('day').toDate().getTime()
                const expirationTime = Math.floor((endDate - new Date().getTime()) / 1000)
                await r.expire(key, expirationTime);
            }
        })
        if (body.count > 0) {
            const d = dayjs()
            const year = d.get('year')
            const month = d.get('month') + 1;
            const day = d.get('date')
            const pkg = log.pkg;
            let one = await m.findOne(KsLiveRoomDayLog, { where: { uuid: body.uuid, year: `${year}`, month: `${month}`, day: `${day}`, pkg } })
            if (!one) {
                one = m.create(KsLiveRoomDayLog, {
                    year: `${year}`, month: `${month}`, day: `${day}`, pkg, count: 0, uuid: body.uuid, owner: device?.owner
                })
                const { id } = await m.save(KsLiveRoomDayLog, one)
                one.id = id;
            }
            await m.update(KsLiveRoomDayLog, one.id, { count: one.count + body.count })
        }
    })
    return toSuccess(result)
}

function toNumber(val: any) {
    if (isNaN(val)) return 0;
    if (typeof val === 'string') return toNumber(parseInt(val))
    if (typeof val === `number`) return val;
    throw new Error(`未知数据`)
}
